<script lang="ts" setup>
import { PropType, ref, watchEffect,nextTick, onMounted,watch,toRaw,reactive,onBeforeUpdate} from 'vue'
import { ChevronsUpDownIcon, PlusIcon, AlertCircleIcon, MinusCircleIcon } from 'lucide-vue-next'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@/components/ui/collapsible'
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectTrigger,
  SelectValue,
  SelectLabel,
  SelectSeparator
} from '@/components/ui/select'
import Navigation from './navigation.vue'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { useNode, useVueFlow } from '@vue-flow/core'
import storeMap from '@/pina/index'
import {
  TreeItem,
  TreeRoot,
  NavigationMenuContent,
  NavigationMenuIndicator,
  NavigationMenuItem,
  NavigationMenuLink,
  NavigationMenuList,
  NavigationMenuRoot,
  NavigationMenuTrigger,
  NavigationMenuViewport
} from 'radix-vue'
import { Icon } from '@iconify/vue'
import { IOutputItem } from '@/lib/types'
import { isArray } from 'lodash'
import {findConnectedNodes} from '@/lib/utils'
type InputItem = {
  name: string
  type?: 'reference' | 'input'
  value: string
  description: string
  category: string
  ref?: string
  Options?:any[]
}

type Option = {
  groupName: string
  options: {
    label: string
    value: string
    id?: string
  }[]
}

interface TreeNode {
  title: string
  icon?: string
  children?: TreeNode[]
}
const props = defineProps({
  staticNameKey: {
    type: [String, Array] as PropType<string | Array<string>>,
    default: ''
  },
  data: {
    type: Array as PropType<InputItem[]>,
    default: () => []
  },
  storeId: {
    type: String,
    default: () => 'useEndStore'
  },
  nodeId: {
    type: String || Number,
    default: 'Plugin_0'
  },
  title:{
    type: String,
    default: '输入'
  }
})

const { data, storeId, staticNameKey, nodeId,title } = props
const isOpen = ref(true)
const selectOpen = ref(false)
const useStore = storeMap[storeId]()
const referenceOptions = ref<Option[]>([])
const node = useNode()
const { getEdges, getNodes,edges} = useVueFlow()
let isTree = ref(false)
watchEffect(() => {
  if (props.staticNameKey) {
    if (typeof props.staticNameKey === 'string') {
      data.push({
        name: props.staticNameKey,
        type: 'reference',
        value: '',
        description: '',
        category: ''
      })
    } else {
      props.staticNameKey.forEach((key) => {
        data.push({
          name: key,
          type: 'reference',
          value: '',
          description: '',
          category: ''
        })
      })
    }
  }
})
 
const dataList = ref([])
watch(()=>props.data,(n,o)=>{
  if(n){
    dataList.value = n;
  }else{
    dataList.value = o;
  }
},{immediate:true,deep:true})
const OptionsStore =storeMap.useOptionsStore()
watch(()=>OptionsStore.selectOptions,(n,o)=>{
  if(n&&Object.values(n).length){
    dataList.value.forEach(item=>{
      if(item.Options){
        const Options = Object.values(n)[0]?.Options
        const groupName = Object.values(n)[0]?.groupName
        const id = Object.values(n)[0]?.id
        const titName = item?.Options[0].label.split('-')[0]
        const OptionId =  item.Options[0].id
        if(titName == groupName&&id == OptionId){
          item.Options =[{
            id,
            label:`${groupName}-${Options[0].value}` ,
            value: Options[0].value
          }]
          item.value = Options[0].value
        }
      }
    })
  }
},{deep:true})
watch(()=>OptionsStore.changeTitle,(n,o)=>{
  handleQueryPrevNodeOutput(true)
  dataList.value.forEach(item=>{
    Object.values(referenceOptions.value).map((el:any,index:number)=>{
      el.Options.map((k,i)=>{
       if(k.value == item.value) {
          const val = item.value;
          const targe =`${el.groupName}-${item.value}`
          item.Options = [{
            id:`${el.groupName}-${i}`,
            label:targe,
            value:val
          }]
        }        
      })
    })
  })
},{deep:true})

onMounted(() => {
  dataList.value = [...data]
  handleQueryPrevNodeOutput(true)
  dataList.value.forEach(item=>{
    Object.values(referenceOptions.value).map((el:any,index:number)=>{
      el.Options.map((k,i)=>{
       if(k.value == item.value) {
          const val = item.value;
          const targe =`${el.groupName}-${item.value}`
          item.Options = [{
            id:`${el.groupName}-${i}`,
            label:targe,
            value:val
          }]
        }        
      })
    })
  })
})


function handleOnClickAddBtnInInput(e: Event) {
  e.stopPropagation()
  isOpen.value = true
  useStore.add()
}
function handleClickDeleteBtnInInput(index: number) {
  useStore.deleteItem(index)
}

type Itarget = {
  [key: string]: boolean
}
const handleSelectedNodePath= (data:any,index:number)=>{
  dataList.value[index].Options = [data];
  dataList.value[index].value =  data.value
  selectOpen.value = false;
  const nodeId = node.id;
    const linkedNodeId = edges.value
    .filter(edge =>edge.target === nodeId)
    .find(edge => edge.source === nodeId ? edge.target : edge.source)?.source;
    linkedNodeId&&storeMap[storeId]().updateRef(linkedNodeId)
    // console.log(node.id,edges.value,linkedNodeId,'edges.valueedges.valueedges.valueedges.valueedges.valueedges.value')
  nextTick()
}
const handleQueryPrevNodeOutput = (flag:boolean) => {
  if (flag) {
    const connectedNodes = [...findConnectedNodes(node.id,getEdges.value,getNodes.value)]
    let selectObj = {}
    connectedNodes.map(item=>{
      item.data.output = item.data.output?item.data.output:[]
      const isSelectTree = item.data?.output[0]?.type=='5';
      let selectDataValue;
      try {
        selectDataValue = JSON.parse(item.data?.output[0].value)
        selectDataValue[0].value = selectDataValue[0].value?selectDataValue[0].value:selectDataValue[0].label
      } catch (error) {
        selectDataValue = item.data?.output[0].value
      }
       selectDataValue = isSelectTree?selectDataValue:item.data?.output
      if(selectDataValue){
        const istree = selectDataValue.some((item: any) => Array.isArray(item.children) && item.children.length > 0)
        const SelectOption = {
          groupName:item.data.title,
          Options:istree?selectDataValue:selectDataValue.map((el:any,index:number)=>{
            return {
              id:`${item.data.title}-${index}`,
              label:el.name||el.label,
              value:el.name||el.label
            }
          })
        }
        selectObj[item.data.title] = SelectOption
      }
    })
    storeMap.useOptionsStore().addReferenceOption(selectObj)
    const OptionsStore = storeMap.useOptionsStore()
    const options = OptionsStore.referenceObject
    referenceOptions.value = {...options}
    
  }
}

</script>


<template>
  <div class="rounded-md bg-muted px-3 py-4">
    <Collapsible v-model:open="isOpen">
      <collapsible-trigger as-child>
        <div class="flex w-full items-center justify-between">
          <div class="flex items-center gap-x-2">
            <chevrons-up-down-icon class="h-4 w-4 cursor-pointer" />
            <p>{{title}}</p>
            <tooltip-provider>
              <tooltip>
                <tooltip-trigger>
                  <alert-circle-icon class="h-3 w-3 text-muted-foreground" />
                </tooltip-trigger>
                <tooltip-content>
                  <p class="max-w-60">请提供需要添加到提示词中的信息，这些信息可以被提示词引用。</p>
                </tooltip-content>
              </tooltip>
            </tooltip-provider>
          </div>
        </div>
      </collapsible-trigger>
      <collapsible-content class="space-y-3 px-3 py-3">
        <div class="flex gap-x-4">
          <Label class="flex-1 text-sm text-muted-foreground">参数名</Label>
          <Label class="w-2/12 text-sm text-muted-foreground">参数值</Label>
          <Label class="flex-1 max-w-28 text-sm text-muted-foreground"></Label>
        </div>
        <div class="flex gap-x-2" v-for="(item, index) in dataList" :key="index">
          <div class="flex-1">
            <p v-if="staticNameKey">
              {{ item.name }}
              <tooltip-provider>
                <tooltip>
                  <tooltip-trigger>
                    <alert-circle-icon class="h-3 w-3 text-muted-foreground" />
                  </tooltip-trigger>
                  <tooltip-content>
                    <p class="max-w-60">
                      {{ item.description }}
                    </p>
                  </tooltip-content>
                </tooltip>
              </tooltip-provider>
            </p>
            <Input v-model="item.name" placeholder="请输入名称" v-else />
          </div>
          <div class="no-gap-radius-right w-2/12">
            <Select v-model="item.category">
              <SelectTrigger class="w-full" as="div">
                <SelectValue placeholder="请选择类型" />
              </SelectTrigger>
              <SelectContent>
                <SelectGroup>
                  <SelectItem value="1"> 引用 </SelectItem>
                  <SelectItem value="2"> 输入 </SelectItem>
                </SelectGroup>
              </SelectContent>
            </Select>
          </div>
          <div class="no-gap-radius-left flex w-6/12 max-w-32 cursor-pointer items-center gap-x-2">
            <Select
             v-model:open="item.selectOpen"
              v-if="item.category === '1'"
              class="text-xs text-gray-400"
              v-model="item.value"
              @update:open="handleQueryPrevNodeOutput"
            >
              <SelectTrigger class="w-full" as="div">
                <SelectValue placeholder="请选择" />
              </SelectTrigger>
              <SelectContent>
                <SelectGroup v-if='item?.Options&&item?.Options[0]?.value'>
                  <SelectItem
                    class="text-gray-500"
                    v-for="option in item?.Options"
                    :key="option.value"
                    :value="option.value"
                  >
                    {{ option.label }}
                  </SelectItem>
                </SelectGroup>
                <!-- <p class="px-2 text-xs text-gray-500 text-muted-foreground" v-else>暂无数据</p> -->
                <!-- <SelectSeparator class="h-[1px] w-full bg-gray-300" /> -->
                <div class="relative">
                  <Navigation :data="referenceOptions"  @update:selectedNodePath="(data)=>handleSelectedNodePath(data,index)" />
                </div>
              </SelectContent>
            </Select>
            <Input v-model="item.value" placeholder="请输入" v-else />
            <minus-circle-icon
              class="h-4 w-4"
              @click="() => handleClickDeleteBtnInInput(index)"
              color="#1c1d2359"
              v-if="!staticNameKey"
            />
          </div>
        </div>
        <Button v-if="!staticNameKey" class="mt-2" @click="handleOnClickAddBtnInInput"><plus-icon class="h-6 w-5 cursor-pointer text-primary" />新增</Button>
      </collapsible-content>
    </Collapsible>
  </div>
</template>
